home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Extensions / Numerical / Lib / ArrayPrinter.py < prev    next >
Encoding:
Text File  |  2000-06-23  |  7.7 KB  |  214 lines

  1. # Array printing function
  2. #
  3. # Written by Konrad Hinsen <hinsenk@ere.umontreal.ca>
  4. # last revision: 1996-3-13
  5. # modified by Jim Hugunin 1997-3-3 for repr's and str's (and other details)
  6.  
  7. import sys
  8. from umath import *
  9. import Numeric
  10.  
  11. def array2string(a, max_line_width = None, precision = None,
  12.                      suppress_small = None, separator=' ',
  13.                      array_output=0):
  14.     """array2string(a, max_line_width = None, precision = None,
  15.                      suppress_small = None, separator=' ',
  16.                      array_output=0)"""
  17.     if len(a.shape) == 0:
  18.         return str(a[0])
  19.  
  20.     if multiply.reduce(a.shape) == 0:
  21.         return "zeros(%s, '%s')" % (a.shape, a.typecode())
  22.  
  23.     if max_line_width is None:
  24.         try:
  25.             max_line_width = sys.output_line_width
  26.         except AttributeError:
  27.             max_line_width = 77
  28.     if precision is None:
  29.         try:
  30.             precision = sys.float_output_precision
  31.         except AttributeError:
  32.             precision = 8
  33.     if suppress_small is None:
  34.         try:
  35.             suppress_small = sys.float_output_suppress_small
  36.         except AttributeError:
  37.             suppress_small = 0
  38.     data = Numeric.ravel(a)
  39.     type = a.typecode()
  40.     items_per_line = a.shape[-1]
  41.     if type == 'b' or type == '1' or type == 's' or type == 'i' \
  42.        or type == 'l':
  43.         max_str_len = max(len(str(maximum.reduce(data))),
  44.                           len(str(minimum.reduce(data))))
  45.         format = '%' + str(max_str_len) + 'd'
  46.         item_length = max_str_len
  47.         format_function = lambda x, f = format: _formatInteger(x, f)
  48.     elif type == 'f' or type == 'd':
  49.         format, item_length = _floatFormat(data, precision, suppress_small)
  50.         format_function = lambda x, f = format: _formatFloat(x, f)
  51.     elif type == 'F' or type == 'D':
  52.         real_format, real_item_length = _floatFormat(data.real, precision,
  53.                                                      suppress_small, sign=0)
  54.         imag_format, imag_item_length = _floatFormat(data.imaginary, precision,
  55.                                                      suppress_small, sign=1)
  56.         item_length = real_item_length + imag_item_length + 3
  57.         format_function = lambda x, f1 = real_format, f2 = imag_format: \
  58.                           _formatComplex(x, f1, f2)
  59.     elif type == 'c':
  60.         item_length = 1
  61.         format_function = lambda x: x
  62.     elif type == 'O':
  63.         item_length = max(map(lambda x: len(str(x)), data))
  64.         format_function = _formatGeneral
  65.     else:
  66.         return str(a)
  67.     final_spaces = (type != 'c')
  68.     item_length = item_length+len(separator)
  69.     line_width = item_length*items_per_line - final_spaces
  70.     if line_width > max_line_width:
  71.         indent = 6
  72.         if indent == item_length:
  73.             indent = 8
  74.         items_first = (max_line_width+final_spaces)/item_length
  75.         if items_first < 1: items_first = 1
  76.         items_continuation = (max_line_width+final_spaces-indent)/item_length
  77.         if items_continuation < 1: items_continuation = 1
  78.         line_width = max(item_length*items_first,
  79.                          item_length*items_continuation+indent) - final_spaces
  80.         number_of_lines = 1 + (items_per_line-items_first +
  81.                                items_continuation-1)/items_continuation
  82.         line_format = (number_of_lines, items_first, items_continuation,
  83.                        indent, line_width, separator)
  84.     else:
  85.         line_format = (1, items_per_line, 0, 0, line_width, separator)
  86.     lst = _arrayToString(a, format_function, len(a.shape), line_format, 6*array_output, 0)[:-1]
  87.     if array_output:
  88.         if a.typecode() in ['l', 'd', 'D']:
  89.             return "array(%s)" % lst
  90.         else:
  91.             return "array(%s,'%s')" % (lst, a.typecode())
  92.     else:
  93.         return lst
  94.         
  95. def _floatFormat(data, precision, suppress_small, sign = 0):
  96.     exp_format = 0
  97.     non_zero = abs(Numeric.compress(not_equal(data, 0), data))
  98.     if len(non_zero) == 0:
  99.         max_val = 0.
  100.         min_val = 0.
  101.     else:
  102.         max_val = maximum.reduce(non_zero)
  103.         min_val = minimum.reduce(non_zero)
  104.         if max_val >= 1.e8:
  105.             exp_format = 1
  106.         if not suppress_small and (min_val < 0.0001 or max_val/min_val > 1000.):
  107.             exp_format = 1
  108.     if exp_format:
  109.         large_exponent = 0 < min_val < 1e-99 or max_val >= 1e100
  110.         max_str_len = 8 + precision + large_exponent
  111.         if sign: format = '%+'
  112.         else: format = '%'
  113.         format = format + str(max_str_len) + '.' + str(precision) + 'e'
  114.         if large_exponent: format = format + '3'
  115.         item_length = max_str_len 
  116.     else:
  117.         format = '%.' + str(precision) + 'f'
  118.         precision = min(precision, max(tuple(map(lambda x, p=precision,
  119.                                                  f=format: _digits(x,p,f),
  120.                                                  data))))
  121.         max_str_len = len(str(int(max_val))) + precision + 2
  122.         if sign: format = '%#+'
  123.         else: format = '%#'
  124.         format = format + str(max_str_len) + '.' + str(precision) + 'f'
  125.         item_length = max_str_len 
  126.     return (format, item_length)
  127.  
  128. def _digits(x, precision, format):
  129.     s = format % x
  130.     zeros = len(s)
  131.     while s[zeros-1] == '0': zeros = zeros-1
  132.     return precision-len(s)+zeros
  133.  
  134. def _arrayToString(a, format_function, rank, line_format, base_indent=0, indent_first=1):
  135.     if rank == 0:
  136.         return str(a[0])
  137.     elif rank == 1:
  138.         s = ''
  139.         s0 = '['
  140.         items = line_format[1]
  141.         if indent_first:
  142.             indent = base_indent
  143.         else:
  144.             indent = 0
  145.         index = 0
  146.         for j in range(line_format[0]):
  147.             s = s + indent * ' '+s0
  148.             for i in range(items):
  149.                 s = s + format_function(a[index])+line_format[-1]
  150.                 index = index + 1
  151.                 if index == a.shape[0]: break
  152.             if s[-1] == ' ': s = s[:-1]
  153.             s = s + '\n'
  154.             items = line_format[2]
  155.             indent = line_format[3]+base_indent
  156.             s0 = ''
  157.         s = s[:-len(line_format[-1])]+']\n'
  158.     else:
  159.         if indent_first:
  160.             s = ' '*base_indent+'['
  161.         else:
  162.             s = '['
  163.         for i in range(a.shape[0]-1):
  164.             s = s + _arrayToString(a[i], format_function, rank-1, line_format, base_indent+1, indent_first=i!=0)
  165.             s = s[:-1]+line_format[-1][:-1]+'\n'
  166.         s = s + _arrayToString(a[a.shape[0]-1], format_function,
  167.                                rank-1, line_format, base_indent+1)
  168.         s = s[:-1]+']\n'
  169.     return s
  170.  
  171. def _formatInteger(x, format):
  172.     return format % x
  173.  
  174. def _formatFloat(x, format, strip_zeros = 1):
  175.     if format[-1] == '3':
  176.         format = format[:-1]
  177.         s = format % x
  178.         third = s[-3]
  179.         if third == '+' or third == '-':
  180.             s = s[1:-2] + '0' + s[-2:]
  181.     elif format[-1] == 'f':
  182.         s = format % x
  183.         if strip_zeros:
  184.             zeros = len(s)
  185.             while s[zeros-1] == '0': zeros = zeros-1
  186.             s = s[:zeros] + (len(s)-zeros)*' '
  187.     else:
  188.         s = format % x
  189.     return s
  190.  
  191. def _formatComplex(x, real_format, imag_format):
  192.     r = _formatFloat(x.real, real_format)
  193.     i = _formatFloat(x.imag, imag_format, 0)
  194.     if imag_format[-1] == 'f':
  195.         zeros = len(i)
  196.         while zeros > 2 and i[zeros-1] == '0': zeros = zeros-1
  197.         i = i[:zeros] + 'j' + (len(i)-zeros)*' '
  198.     else:
  199.         i = i + 'j'
  200.     return r + i
  201.  
  202. def _formatGeneral(x):
  203.     return str(x) + ' '
  204.  
  205. if __name__ == '__main__':
  206.     a = Numeric.arange(10)
  207.     b = Numeric.array([a, a+10, a+20])
  208.     c = Numeric.array([b,b+100, b+200])
  209.     print array2string(a)
  210.     print array2string(b)
  211.     print array2string(sin(c), separator=', ', array_output=1)
  212.     print array2string(sin(c)+1j*cos(c), separator=', ', array_output=1)
  213.     print array2string(Numeric.array([[],[]]))
  214.